<?php
	include("lib/xmlrpc.inc");
	/**
	* FreeswitchRPC Library. v1.00a.
	* ---------------------------------------------------------------------------
	* @author Matt Austin matt@m-austin.com
	* @package FreeswitchRPC
	* @description RPC interface to freeswitch commands
	*
	* ex: 
	*  $client = new FreeswitchRPC("localhost", 8081, 'freeswitch', 'works');
	*  print_r($client->showChannels())
	*/ 

	class FSRPCException extends Exception { }

	class FreeswitchRPC extends xmlrpc_client
	{
		// do connection and login in the constructer 
		function __construct($address='localhost', $port='8080', $username='freeswitch', $password='works'){
			$this->xmlrpc_client("/RPC2", $address, $port);
			$this->setCredentials($username,$password,NULL);
			# we should check the connection here... but none of the
			# functions above require or return a working connection 
			# maybe can can just try to send an echo to freeswitch 
		}

		/**
		* reloadXML
		* ------------------------------------------
		* Reload all XML confs in freeswitch
		*
		* @param none
		* @return true/false.
		*/ 
		public function reloadXML(){
			$result = $this->RPCSend("reloadxml", "");
			
			# remove trailing returns
			$result = preg_replace('/[\n]+$/', '', $result);
			
			if($result == "+OK [Success]"){
				return true;
			}
			else{
				# not too sure what else this function could return,
				# but anything but ok cant be good
				return false;
				# return $result;
			}			 
		}

		/**
		* showChannels
		* ------------------------------------------
		* Show the channel data from your freeswitch
		*
		* @param none
		* @return array of hashes with chan info.
		*/ 
		public function showChannels(){
			$result = $this->RPCSend("show", "channels");
			return $this->_parseTable($result);			 
		}

		/**
		* showCalls
		* ------------------------------------------
		* Show the call data from your freeswitch
		*
		* @param none
		* @return array of hashes with chan info.
		*/ 
		public function showCalls(){
			$result = $this->RPCSend("show", "calls");
			return $this->_parseTable($result);			 
		}

		/**
		* shutdown
		* ------------------------------------------
		* Shutdown freeswitch
		*
		* @param none
		* @return true/false.
		*/ 
		public function shutdown(){
			$result = $this->RPCSend("fsctl", "shutdown");
			
			# remove trailing returns
			$result = preg_replace('/[\n]+$/', '', $result);
			
			if($result == "+OK"){
				return true;
			}
			else{
				# not too sure what else this function could return,
				# but anything but ok cant be good
				
				return false;
				# return $result;
			}			 
		}

		/**
		* RPCSend
		* send command to freeswitch 
		*
		* @param string, [string,..]  ex: $FSRPC->RPCSend("show", "channels");
		* @return string (raw string from rpc)
		* @throws FSRPCException on error.
		*/ 			
		public function RPCSend(){
			$args = func_get_args();
			
			$command = array_shift($args);
			$argString = join(" ", $args);
			
			# build an RPC message
			$msg = new xmlrpcmsg('freeswitch.api',
				array(
					new xmlrpcval($command, "string"),
					new xmlrpcval($argString, "string")
				)  
			);
			# send to server and catch error
			$response = $this->send($msg);
			if (!$response || $response->faultCode()) {
				throw new FSRPCException("RPC ERROR:".$response->faultString(), $response->faultCode());
			}
			else{
				$result = php_xmlrpc_decode($response->value());
				$this->{'lastResult'} = $result;
				return $result;
			}				
		}
		
		
		
		/**
		* _parseTable
		* converts a string of table data to an array of arrays 
		*
		* @param string
		* @return array(
		*			array( 
		*				key=>val,key=>val, key=>val
		*			)
		*		);
		*/ 			
		private function _parseTable($string){
			
			$rows = array();			
			$lines = split("\n", $string);
			
			# remove the summary 
			array_pop($lines);
			$summary = array_pop($lines);
			array_pop($lines);
			
			# get the headers
			$headers = split(",",array_shift($lines));

			# build array or arrays
			foreach ($lines as $line)
			{
				$_row = split(",",$line);
				if(sizeof($_row) == sizeof($headers)){
					$row = array_combine($headers, $_row);
					array_push($rows,$row);
				}
				else{
					throw new FSRPCException("RPC table parse error");
				}
			}

			return $rows;			
		}		
		
	}
	
?>